package no.nordicsemi.android.dfuupdate.scanner;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelUuid;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import no.nordicsemi.android.dfuupdate.R;
import no.nordicsemi.android.dfuupdate.bean.PutTag;
import no.nordicsemi.android.dfuupdate.bean.UpdateTag;
import no.nordicsemi.android.dfuupdate.dfu.SelectFileAutoActivity;
import no.nordicsemi.android.dfuupdate.dfu.SelectedFileActivity;
import no.nordicsemi.android.dfuupdate.server.TaskService;
import no.nordicsemi.android.dfuupdate.utility.DeviceIdUtil;
import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat;
import no.nordicsemi.android.support.v18.scanner.ScanCallback;
import no.nordicsemi.android.support.v18.scanner.ScanFilter;
import no.nordicsemi.android.support.v18.scanner.ScanResult;
import no.nordicsemi.android.support.v18.scanner.ScanSettings;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/*
* 自动更新
* */
public class ScanAutoActivity  extends AppCompatActivity {

    private String TAG = "ScanAutoActivity";
    private final static long SCAN_DURATION = 60000*3;
    private final static String PARAM_UUID = "param_uuid";
    private final static int REQUEST_PERMISSION_REQ_CODE = 34;
    private BluetoothAdapter bluetoothAdapter;
    private BtchDeviceListAdapter deviceListAdapter;
    private final Handler handler = new Handler();
    private Button scanButton;
    private View permissionRationale;
    private ParcelUuid uuid;
    private  boolean scanning = false;
    private SearchView searchView;
    public static String keyWord;
    private TextView Count;
    //选择文件的路径
    private String selectFileUri = "";
    //标签的升级状态
    private int tag_update_status = 0;
    private String baseUrl="http://103.229.214.118:8099/";//retrofit要求以/结束,否则会产生错误
    private int update_id = 0;
    private double update_swver = 1.1;
    private int status = 1;
    private String uuids;
    private String updateMacAdd="";
    private int selectUpdateId[] = {62,195,2379};
    private int select_id =0;
    private Handler handlers = new Handler();
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan_auto);
        Log.d("KEYWORDDD", String.valueOf(keyWord == null));
        uuids = DeviceIdUtil.getIMEIDeviceId(getApplicationContext());
        Log.d("uuid =",uuids);
      //  getUpdateTag(update_id,update_swver,uuids);
        //test
       // getUpdateTag(selectUpdateId[select_id],update_swver,uuids);
        setGui();
        //addBoundDevices();
//        if(savedInstanceState == null) {
//            startScan();
//        }
        //PS:如下
        // handlers.postDelayed(runnable, 100 * 1);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        return super.onOptionsItemSelected(item);
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    protected void setGui() {

        final Toolbar toolbar  = findViewById(R.id.toolbar_actionbar);
        setSupportActionBar(toolbar);
        Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);



        final ListView listView = (ListView) findViewById(R.id.batch_list);
        listView.setEmptyView((findViewById(android.R.id.empty)));

        listView.setAdapter(deviceListAdapter = new BtchDeviceListAdapter());

        listView.setOnItemClickListener((parent, view, position, id) -> {
            // 选择单个标签
            final ExtendedBluetoothDevice d = (ExtendedBluetoothDevice) deviceListAdapter.getItem(position);
            final String mac = d.device.getAddress();
            final String name = d.device.getName();
            Intent intent = new Intent(ScanAutoActivity.this, SelectFileAutoActivity.class);
            Bundle bundle = new Bundle();
            ArrayList<String> selected = new ArrayList<String>();
//            for(ExtendedBluetoothDevice dev : deviceListAdapter.getDevices()) {
//                if(deviceListAdapter.findMap(dev.device.getAddress())) {
                    BleDev temp = new BleDev(name,mac);
                    selected.add(JSON.toJSONString(temp));
//                }
//            }
            bundle.putStringArrayList("SELECTED_DEVICES", selected);
            bundle.putString("SELECT_FILE_URI",selectFileUri);
            intent.putExtras(bundle);
          //  startActivity(intent);
            //得到新打开Activity关闭后返回的数据
            //第二个参数为请求码，可以根据业务需求自己编号
            startActivityForResult(intent, 1);
            //finish();
            stopScan();

        });
        listView.setTextFilterEnabled(true);

        Count = (TextView) findViewById(R.id.bat_count);

        scanButton = (Button) findViewById(R.id.action_cancel);
        scanButton.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onClick(View v) {
                if(v.getId() == R.id.action_cancel) {
                    if(scanning) {
                        stopScan();
                    } else {
                        startScan();
                    }
                }
            }
        });

    }
    @RequiresApi(api = Build.VERSION_CODES.M)
    private Runnable runnable = new Runnable() {
        public void run() {
            this.update();
           // handlers.postDelayed(this, SCAN_DURATION);// 间隔2秒
        }
        void update() {
            //刷新msg的内容
//            stopScan();
//            startScan();
            getUpdateTag(selectUpdateId[select_id],update_swver,uuids);

        }
    };


    @RequiresApi(api = Build.VERSION_CODES.M)
    private void startScan() {
        if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION) && permissionRationale.getVisibility() == View.GONE){
                permissionRationale.setVisibility(View.VISIBLE);
                return;
            }

            requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSION_REQ_CODE);
            return;
        }
        deviceListAdapter.clearDevices();
        scanButton.setText("Cancel");

        final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
        final ScanSettings settings = new ScanSettings.Builder()
                .setLegacy(false)
               // .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).setReportDelay(1000)
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).setReportDelay(100)
                .setUseHardwareBatchingIfSupported(false).build();
        final List<ScanFilter> filters = new ArrayList<>();
        filters.add(new ScanFilter.Builder().setServiceUuid(uuid).build());
        scanner.startScan(filters,settings,scanCallback);

        scanning = true;
//        handler.postDelayed(() -> {
//            if(scanning) {
//                stopScan();
//            }
//          //  getUpdateTag(selectUpdateId[select_id],update_swver,uuids);
//        },SCAN_DURATION);
        handlers.postDelayed(runnable, SCAN_DURATION);
    }


    @RequiresApi(api = Build.VERSION_CODES.M)
    private void stopScan() {
        if(scanning) {
            scanButton.setText("Scan");
            final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
            scanner.stopScan(scanCallback);
            scanning = false;
        }
        handlers.removeCallbacks(runnable);  //停止Timer
    }

    private ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(final int callbackType, @NonNull final ScanResult result) {
          //  Log.d("TAGGGG", result.getDevice().getAddress());
//            if(result.getDevice().getAddress().equals("FA:E6:DA:85:3A:19")){
//                Log.d("TAGGGG0", result.getDevice().getAddress());
//                goToSelectFileActivity(result.getDevice().getName(),result.getDevice().getAddress());
//            }
        }

        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onBatchScanResults(@NonNull final List<ScanResult> results) {
           // String testData = getFilterMac(updateMacAdd);
            for (final ScanResult result : results) {
               // if( getFilterMac(result.getDevice().getAddress()).equals(updateMacAdd)){
                    if(result.getDevice().getAddress().equals("FA:E6:DA:85:3A:19")){
                    Log.d("TAGGGG1", result.getDevice().getAddress());
                    goToSelectFileActivity(result.getDevice().getName(),result.getDevice().getAddress());
                }
            }

            deviceListAdapter.update(results);
            if(deviceListAdapter.getMapCount() == 0)
                Count.setText("count : " + deviceListAdapter.getItemCount());
            else
                Count.setText("count : " + deviceListAdapter.getItemCount() + ", selected : " + deviceListAdapter.getMapCount());

        }

        @Override
        public void onScanFailed(final int errorCode) {
            // should never be called
        }
    };

    private void addBoundDevices() {
        final Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();
        deviceListAdapter.addBondedDevices(devices);
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onResume() {
        Log.d("SBR", "onResume");
        Log.d("KEY", String.valueOf(keyWord));
        super.onResume();
//        if(!scanning)
//            startScan();
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopScan();
    }
    private String getFilterMac(String mac){
        String newMac = "";
        if(!TextUtils.isEmpty(mac)){
            newMac = mac.replaceAll(":","").trim();
        }
        return newMac;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void goToSelectFileActivity(String name, String mac){
        Intent intent = new Intent(ScanAutoActivity.this, SelectFileAutoActivity.class);
        Bundle bundle = new Bundle();
        ArrayList<String> selected = new ArrayList<String>();
        BleDev temp = new BleDev(name,mac);
        selected.add(JSON.toJSONString(temp));
        bundle.putStringArrayList("SELECTED_DEVICES", selected);
        bundle.putString("SELECT_FILE_URI",selectFileUri);
        intent.putExtras(bundle);
      //  startActivity(intent);
        //得到新打开Activity关闭后返回的数据
        //第二个参数为请求码，可以根据业务需求自己编号
        startActivityForResult(intent, 1);
        stopScan();
    }

    /*
     * 获取需要升级标签
     * */

    private void getUpdateTag(int id ,double swver,String uuid){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)//设置项目路径 其它路径都改成相对路径 与ApiUrls   HOST    HOME=HOST+"/home"/
                .addConverterFactory(GsonConverterFactory.create(new Gson()))//convert就是将json解析成javaBean
                .build();//执行创建方法

        //调用retrofit框架去读到一个请求需要的全部参数,参数都是注解或者泛型来标注
        TaskService taskService = retrofit.create(TaskService.class);//读取请求方式 请求页面 返回参数

        HashMap<String, Object> params=new HashMap<>();
        params.put("id",id);
        params.put("swver",swver);
        params.put("uuid",uuid);
        Call<UpdateTag> method = taskService.getTag(params);

        //执行子线程，处理服务端返回数据 都是将数据传给回调对象(空方法，给开发者编写业务逻辑，注意条件)
        Callback<UpdateTag> callback=new Callback<UpdateTag>() {
            //处理请求成功的业务逻辑
            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onResponse(Call<UpdateTag> call, Response<UpdateTag> response) {
                //从响应里面获取解析后的javaBean
                UpdateTag data = response.body();
                Log.i("data===",data.getMsg()+"   "+data.getStat());

                stopScan();
                startScan();
                if (data != null &&data.getStat().equals("SUCCESS")) {
                    update_id = data.getData().getId();
                    update_swver = data.getData().getSwver();
                    updateMacAdd = data.getData().getMacId();
//                    Log.i("data====",data.getData().getMacId());
                    if(TextUtils.isEmpty(updateMacAdd)){
                      //  startScan();
                    }
                }
            }
            //处理请求失败的业务逻辑
            @Override
            public void onFailure(Call<UpdateTag> call, Throwable t) {
                t.printStackTrace();
                Toast.makeText(ScanAutoActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        };
        method.enqueue(callback);
    }


    /*
     * 上传升级标签状态
     * */

    private void putTag(int id ,double swver,String uuid,int status){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)//设置项目路径 其它路径都改成相对路径 与ApiUrls   HOST    HOME=HOST+"/home"/
                .addConverterFactory(GsonConverterFactory.create(new Gson()))//convert就是将json解析成javaBean
                .build();//执行创建方法

        //调用retrofit框架去读到一个请求需要的全部参数,参数都是注解或者泛型来标注
        TaskService taskService = retrofit.create(TaskService.class);//读取请求方式 请求页面 返回参数

        HashMap<String, Object> params=new HashMap<>();
        params.put("id",id);
        params.put("swver",swver);
        params.put("uuid",uuid);
        params.put("status",status);
        Call<PutTag> method = taskService.putTag(params);

        //执行子线程，处理服务端返回数据 都是将数据传给回调对象(空方法，给开发者编写业务逻辑，注意条件)
        Callback<PutTag> callback=new Callback<PutTag>() {
            //处理请求成功的业务逻辑
            @Override
            public void onResponse(Call<PutTag> call, Response<PutTag> response) {
                //从响应里面获取解析后的javaBean
                PutTag data = response.body();
                Log.i("data===",data.getMsg()+"   "+data.getStat());
                if (data != null &&data.getStat().equals("SUCCESS")) {
                    update_id = data.getData().getId();
                    update_swver = data.getData().getSwver();
                    Log.i("data====",data.getData().getMacId());
                }
            }
            //处理请求失败的业务逻辑
            @Override
            public void onFailure(Call<PutTag> call, Throwable t) {
                t.printStackTrace();
                Toast.makeText(ScanAutoActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        };
        method.enqueue(callback);
    }



    /**
     * 为了得到传回的数据，必须在前面的Activity中（指MainActivity类）重写onActivityResult方法
     *
     * requestCode 请求码，即调用startActivityForResult()传递过去的值
     * resultCode 结果码，结果码用于标识返回数据来自哪个新Activity
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        String result = data.getExtras().getString("result");//得到新Activity 关闭后返回的数据
        selectFileUri = data.getExtras().getString("result");
        tag_update_status = data.getExtras().getInt("update_status");
        Log.i("ScanAutoActivityss0", result+"    "+tag_update_status);
        if(!TextUtils.isEmpty(result)){
            //上次升级标签状态
            // putTag(update_id,update_swver,uuids,tag_update_status);
            //test
            putTag(selectUpdateId[select_id],update_swver,uuids,tag_update_status);
            //test
            if(select_id<2){
                select_id++;
            }else{
                select_id = -1;
            }

            //获取需要升级的标签
            // getUpdateTag(update_id,update_swver,uuids);
            //test
           // getUpdateTag(selectUpdateId[select_id],update_swver,uuids);
            startScan();
        }else{
            Toast.makeText(ScanAutoActivity.this, "选择的文件路劲为空", Toast.LENGTH_SHORT).show();
        }
    }
}
